home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 23 / Amiga Format AFCD23 (Feb 1998, Issue 107).iso / mui / mui_developer / c / examples / class2.c < prev    next >
C/C++ Source or Header  |  1997-03-10  |  9KB  |  347 lines

  1. #include "demo.h"
  2.  
  3.  
  4. /***************************************************************************/
  5. /* Here is the beginning of our simple new class...                        */
  6. /***************************************************************************/
  7.  
  8. /*
  9. ** This class is the same as within Class1.c except that it features
  10. ** a pen attribute.
  11. */
  12.  
  13. struct MyData
  14. {
  15.     struct MUI_PenSpec penspec;
  16.     LONG pen;
  17.     BOOL penchange;
  18. };
  19.  
  20.  
  21. #define MYATTR_PEN 0x8022   /* tag value for the new attribute.            */
  22.  
  23.  
  24. SAVEDS ULONG mNew(struct IClass *cl,Object *obj,Msg msg)
  25. {
  26.     struct MyData *data;
  27.     struct TagItem *tags,*tag;
  28.  
  29.     if (!(obj = (Object *)DoSuperMethodA(cl,obj,msg)))
  30.         return(0);
  31.  
  32.     data = INST_DATA(cl,obj);
  33.  
  34.     /* parse initial taglist */
  35.  
  36.     for (tags=((struct opSet *)msg)->ops_AttrList;tag=NextTagItem(&tags);)
  37.     {
  38.         switch (tag->ti_Tag)
  39.         {
  40.             case MYATTR_PEN:
  41.                 if (tag->ti_Data)
  42.                     data->penspec = *((struct MUI_PenSpec *)tag->ti_Data);
  43.                 break;
  44.         }
  45.     }
  46.  
  47.     return((ULONG)obj);
  48. }
  49.  
  50.  
  51.  
  52. SAVEDS ULONG mDispose(struct IClass *cl,Object *obj,Msg msg)
  53. {
  54.     /* OM_NEW didnt allocates something, just do nothing here... */
  55.     return(DoSuperMethodA(cl,obj,msg));
  56. }
  57.  
  58.  
  59. /*
  60. ** OM_SET method, we need to see if someone changed the penspec attribute.
  61. */
  62.  
  63. SAVEDS ULONG mSet(struct IClass *cl,Object *obj,Msg msg)
  64. {
  65.     struct MyData *data = INST_DATA(cl,obj);
  66.     struct TagItem *tags,*tag;
  67.  
  68.     for (tags=((struct opSet *)msg)->ops_AttrList;tag=NextTagItem(&tags);)
  69.     {
  70.         switch (tag->ti_Tag)
  71.         {
  72.             case MYATTR_PEN:
  73.                 if (tag->ti_Data)
  74.                 {
  75.                     data->penspec = *((struct MUI_PenSpec *)tag->ti_Data);
  76.                     data->penchange = TRUE;
  77.                     MUI_Redraw(obj,MADF_DRAWOBJECT); /* redraw ourselves completely */
  78.                 }
  79.                 break;
  80.         }
  81.     }
  82.  
  83.     return(DoSuperMethodA(cl,obj,msg));
  84. }
  85.  
  86.  
  87. /*
  88. ** OM_GET method, see if someone wants to read the color.
  89. */
  90.  
  91. static ULONG mGet(struct IClass *cl,Object *obj,Msg msg)
  92. {
  93.     struct MyData *data = INST_DATA(cl,obj);
  94.     ULONG *store = ((struct opGet *)msg)->opg_Storage;
  95.  
  96.     switch (((struct opGet *)msg)->opg_AttrID)
  97.     {
  98.         case MYATTR_PEN: *store = (ULONG)&data->penspec; return(TRUE);
  99.     }
  100.  
  101.     return(DoSuperMethodA(cl,obj,msg));
  102. }
  103.  
  104.  
  105. SAVEDS ULONG mSetup(struct IClass *cl,Object *obj,Msg msg)
  106. {
  107.     struct MyData *data = INST_DATA(cl,obj);
  108.  
  109.     if (!DoSuperMethodA(cl,obj,msg))
  110.         return(FALSE);
  111.  
  112.     data->pen = MUI_ObtainPen(muiRenderInfo(obj),&data->penspec,0);
  113.  
  114.     return(TRUE);
  115. }
  116.  
  117.  
  118. SAVEDS ULONG mCleanup(struct IClass *cl,Object *obj,Msg msg)
  119. {
  120.     struct MyData *data = INST_DATA(cl,obj);
  121.  
  122.     MUI_ReleasePen(muiRenderInfo(obj),data->pen);
  123.  
  124.     return(DoSuperMethodA(cl,obj,msg));
  125. }
  126.  
  127.  
  128. SAVEDS ULONG mAskMinMax(struct IClass *cl,Object *obj,struct MUIP_AskMinMax *msg)
  129. {
  130.     /*
  131.     ** let our superclass first fill in what it thinks about sizes.
  132.     ** this will e.g. add the size of frame and inner spacing.
  133.     */
  134.  
  135.     DoSuperMethodA(cl,obj,msg);
  136.  
  137.     /*
  138.     ** now add the values specific to our object. note that we
  139.     ** indeed need to *add* these values, not just set them!
  140.     */
  141.  
  142.     msg->MinMaxInfo->MinWidth  += 100;
  143.     msg->MinMaxInfo->DefWidth  += 120;
  144.     msg->MinMaxInfo->MaxWidth  += 500;
  145.  
  146.     msg->MinMaxInfo->MinHeight += 40;
  147.     msg->MinMaxInfo->DefHeight += 90;
  148.     msg->MinMaxInfo->MaxHeight += 300;
  149.  
  150.     return(0);
  151. }
  152.  
  153.  
  154. /*
  155. ** Draw method is called whenever MUI feels we should render
  156. ** our object. This usually happens after layout is finished
  157. ** or when we need to refresh in a simplerefresh window.
  158. ** Note: You may only render within the rectangle
  159. **       _mleft(obj), _mtop(obj), _mwidth(obj), _mheight(obj).
  160. */
  161.  
  162. SAVEDS ULONG mDraw(struct IClass *cl,Object *obj,struct MUIP_Draw *msg)
  163. {
  164.     struct MyData *data = INST_DATA(cl,obj);
  165.     int i;
  166.  
  167.     /*
  168.     ** let our superclass draw itself first, area class would
  169.     ** e.g. draw the frame and clear the whole region. What
  170.     ** it does exactly depends on msg->flags.
  171.     */
  172.  
  173.     DoSuperMethodA(cl,obj,msg);
  174.  
  175.     /*
  176.     ** if MADF_DRAWOBJECT isn't set, we shouldn't draw anything.
  177.     ** MUI just wanted to update the frame or something like that.
  178.     */
  179.  
  180.     if (!(msg->flags & MADF_DRAWOBJECT))
  181.         return(0);
  182.  
  183.     /*
  184.     ** test if someone changed our pen
  185.     */
  186.  
  187.     if (data->penchange)
  188.     {
  189.         data->penchange = FALSE;
  190.         MUI_ReleasePen(muiRenderInfo(obj),data->pen);
  191.         data->pen = MUI_ObtainPen(muiRenderInfo(obj),&data->penspec,0);
  192.     }
  193.  
  194.     /*
  195.     ** ok, everything ready to render...
  196.     ** Note that we *must* use the MUIPEN() macro before actually
  197.     ** using pens from MUI_ObtainPen() in rendering calls.
  198.     */
  199.  
  200.     SetAPen(_rp(obj),MUIPEN(data->pen));
  201.  
  202.     for (i=_mleft(obj);i<=_mright(obj);i+=5)
  203.     {
  204.         Move(_rp(obj),_mleft(obj),_mtop(obj));
  205.         Draw(_rp(obj),i,_mbottom(obj));
  206.         Move(_rp(obj),_mright(obj),_mtop(obj));
  207.         Draw(_rp(obj),i,_mbottom(obj));
  208.     }
  209.  
  210.     return(0);
  211. }
  212.  
  213.  
  214. /*
  215. ** Here comes the dispatcher for our custom class. We only need to
  216. ** care about MUIM_AskMinMax and MUIM_Draw in this simple case.
  217. ** Unknown/unused methods are passed to the superclass immediately.
  218. */
  219.  
  220. SAVEDS ASM ULONG MyDispatcher(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) Msg msg)
  221. {
  222.     switch (msg->MethodID)
  223.     {
  224.         case OM_NEW        : return(mNew      (cl,obj,(APTR)msg));
  225.         case OM_DISPOSE    : return(mDispose  (cl,obj,(APTR)msg));
  226.         case OM_SET        : return(mSet      (cl,obj,(APTR)msg));
  227.         case OM_GET        : return(mGet      (cl,obj,(APTR)msg));
  228.         case MUIM_AskMinMax: return(mAskMinMax(cl,obj,(APTR)msg));
  229.         case MUIM_Setup    : return(mSetup    (cl,obj,(APTR)msg));
  230.         case MUIM_Cleanup  : return(mCleanup  (cl,obj,(APTR)msg));
  231.         case MUIM_Draw     : return(mDraw     (cl,obj,(APTR)msg));
  232.     }
  233.  
  234.     return(DoSuperMethodA(cl,obj,msg));
  235. }
  236.  
  237.  
  238.  
  239. /***************************************************************************/
  240. /* Thats all there is about it. Now lets see how things are used...        */
  241. /***************************************************************************/
  242.  
  243. int main(int argc,char *argv[])
  244. {
  245.     Object *app,*window,*MyObj,*pen;
  246.     struct MUI_CustomClass *mcc;
  247.     struct MUI_PenSpec *startpen;
  248.  
  249.     init();
  250.  
  251.     /* Create the new custom class with a call to MUI_CreateCustomClass(). */
  252.     /* Caution: This function returns not a struct IClass, but a           */
  253.     /* struct MUI_CustomClass which contains a struct IClass to be         */
  254.     /* used with NewObject() calls.                                        */
  255.     /* Note well: MUI creates the dispatcher hook for you, you may         */
  256.     /* *not* use its h_Data field! If you need custom data, use the        */
  257.     /* cl_UserData of the IClass structure!                                */
  258.  
  259.     if (!(mcc = MUI_CreateCustomClass(NULL,MUIC_Area,NULL,sizeof(struct MyData),MyDispatcher)))
  260.         fail(NULL,"Could not create custom class.");
  261.  
  262.     app = ApplicationObject,
  263.         MUIA_Application_Title      , "Class2",
  264.         MUIA_Application_Version    , "$VER: Class2 19.5 (12.02.97)",
  265.         MUIA_Application_Copyright  , "©1993, Stefan Stuntz",
  266.         MUIA_Application_Author     , "Stefan Stuntz",
  267.         MUIA_Application_Description, "Demonstrate the use of custom classes.",
  268.         MUIA_Application_Base       , "CLASS2",
  269.  
  270.         SubWindow, window = WindowObject,
  271.             MUIA_Window_Title, "Another Custom Class",
  272.             MUIA_Window_ID   , MAKE_ID('C','L','S','2'),
  273.             WindowContents, VGroup,
  274.  
  275.                 Child, TextObject,
  276.                     TextFrame,
  277.                     MUIA_Background, MUII_TextBack,
  278.                     MUIA_Text_Contents, "\33cThis is a custom class with attributes.\nClick on the button at the bottom of\nthe window to adjust the color.",
  279.                     End,
  280.  
  281.                 Child, MyObj = NewObject(mcc->mcc_Class,NULL,
  282.                     TextFrame,
  283.                     MUIA_Background, MUII_BACKGROUND,
  284.                     TAG_DONE),
  285.  
  286.                 Child, HGroup, MUIA_Weight, 10,
  287.                     Child, FreeLabel("Custom Class Color:"),
  288.                     Child, pen = PoppenObject,
  289.                         MUIA_CycleChain, 1,
  290.                         MUIA_Window_Title, "Custom Class Color",
  291.                         End,
  292.                     End,
  293.  
  294.                 End,
  295.  
  296.             End,
  297.         End;
  298.  
  299.     if (!app)
  300.         fail(app,"Failed to create Application.");
  301.  
  302.     DoMethod(window,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,
  303.         app,2,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);
  304.  
  305.     DoMethod(pen,MUIM_Notify,MUIA_Pendisplay_Spec,MUIV_EveryTime,
  306.         MyObj,3,MUIM_Set,MYATTR_PEN,MUIV_TriggerValue);
  307.  
  308.     DoMethod(pen,MUIM_Pendisplay_SetMUIPen,MPEN_HALFSHINE);
  309.  
  310.     get(pen,MUIA_Pendisplay_Spec,&startpen);
  311.     set(MyObj,MYATTR_PEN,startpen);
  312.  
  313. /*
  314. ** This is the ideal input loop for an object oriented MUI application.
  315. ** Everything is encapsulated in classes, no return ids need to be used,
  316. ** we just check if the program shall terminate.
  317. ** Note that MUIM_Application_NewInput expects sigs to contain the result
  318. ** from Wait() (or 0). This makes the input loop significantly faster.
  319. */
  320.  
  321.     set(window,MUIA_Window_Open,TRUE);
  322.  
  323.     {
  324.         ULONG sigs = 0;
  325.  
  326.         while (DoMethod(app,MUIM_Application_NewInput,&sigs) != MUIV_Application_ReturnID_Quit)
  327.         {
  328.             if (sigs)
  329.             {
  330.                 sigs = Wait(sigs | SIGBREAKF_CTRL_C);
  331.                 if (sigs & SIGBREAKF_CTRL_C) break;
  332.             }
  333.         }
  334.     }
  335.  
  336.     set(window,MUIA_Window_Open,FALSE);
  337.  
  338.  
  339. /*
  340. ** Shut down...
  341. */
  342.  
  343.     MUI_DisposeObject(app);     /* dispose all objects. */
  344.     MUI_DeleteCustomClass(mcc); /* delete the custom class. */
  345.     fail(NULL,NULL);            /* exit, app is already disposed. */
  346. }
  347.